with linked_list;
with ada.finalization; use ada.finalization;
generic
    type element_t is private;
    max : natural;
    with procedure print (item : in element_t);
package generic_stack is

    type stack is new controlled with private;
    type stack_a is access stack;

    subtype stackRange is Integer range 0..max;

   package stack_list is new linked_list (element_t, print);
   use stack_list;
    
    
    function len ( in_stack : stack_a ) return stackRange;
    function isempty( in_stack : stack_a ) return boolean;
    procedure push ( in_stack : in out stack_a; element : in element_t);
    procedure pop ( in_stack : in out stack_a; element : out element_t);
    procedure top ( in_stack : in stack_a; element : out element_t);

    stack_overflow, stack_underflow : exception;

private
    type stack is new controlled with
	record
	    length : stackRange := 0;
	    stack_list : list_a;
	    top_link : link_a;
	end record;
    procedure initialize (object : in out stack);
    procedure adjust (object : in out stack);
    procedure finalize (object : in out stack);

end generic_stack;
